(function () {

	var	express = require("express"),
		Repository = require("./Repository"),
		Serializer = require("./Serializer"),
		Deserializer = require("./Deserializer"),
		typeMappings = require("./typeMappings");

	var documentHeaderRegex = /<\?xml[^>]*>/;
	var documentStartTag = "<Zadanie>";
	var documentEndTag = "</Zadanie>";
	function preprocessBody(body) {
		body = body
			.replace(documentHeaderRegex, "")
			.replace(documentStartTag, "")
			.replace(documentEndTag, "")
			.trim();
		var parts = [];
		var match;
		while (body.length > 0 && (match = body.match(/<(\w+)>/))) {
			var tagName = match[1];
			var index = body.match(new RegExp("<\\/" + tagName + ">")).index + tagName.length + 3;
			parts.push(body.substring(0, index));
			body = body.substring(index);
		}
		return parts;
	}

	function Server(port, dataSource) {
		var app = express();
		app.use(express.bodyParser());

		var repository = new Repository(dataSource);

		app.all("*", function (request, response) {
			var body = "";
			request.setEncoding("utf8");
			request.on("data", function (chunk) { body += chunk; });
			request.on("end", function () {
				try {
					var responseBody = '<?xml version="1.0" encoding="utf-8"?>';
					responseBody += "<Odpowiedz>";
					var parts = preprocessBody(body);
					for (var i in parts) {
						var dataRequest = (new Deserializer(typeMappings)).deserialize(parts[i]);
						var result = repository.processRequest(dataRequest);
						if (!Array.isArray(result)) result = [result];
						for (var j in result) {
							responseBody += (new Serializer()).serialize(result[j]);
						}
					}
					responseBody += "</Odpowiedz>";

					response.status(200);
					response.type("application/xml");
					response.send(responseBody);
					response.end();
				} catch (error) {
					response.status(500).send("[ERROR] " + error);
					response.end();
				}
			});
		});

		this.start = function() {
			app.listen(port);
		};
	}

	module.exports = Server;
	
})();